package com.services.ws.auditoria;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLStreamHandler;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.xml.soap.MessageFactory;
import javax.xml.soap.MimeHeaders;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPConnection;
import javax.xml.soap.SOAPConnectionFactory;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.services.ws.auditoria.model.ListAbreviatura;
import com.services.ws.auditoria.model.OpcionesUsuarioRequest;
import com.services.ws.auditoria.model.OpcionesUsuarioResponse;

public class LeerOpcionesPorUsuarioManager {
	
	private static Logger logger;
	private String 				address;
	private String    			service;
	private static String		url;
	private int 				port;
	private final static String soapEnvelopeStartTag = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ws=\"http://pe/com/claro/esb/services/auditoria/ws\" "
			+ "xmlns:opc=\"http://pe/com/claro/esb/services/auditoria/schemas/accesos/OpcionesUsuario.xsd\">  <soapenv:Header/>  <soapenv:Body>";
			
	private final static String soapEnvelopeEndTag = "</soapenv:Body></soapenv:Envelope>";
	
	public LeerOpcionesPorUsuarioManager(String address, int port, String service) throws Exception {  
		this.address = 	address;
		this.port = 	port;
		this.service = 	service;	
		try{
			logger = LoggerFactory.getLogger(LeerOpcionesPorUsuarioManager.class);
		} catch (Exception e){
			System.out.println("The EbsAuditoriaManager logger could not be initialized: " + e.getMessage());
		}
			
		init();
	}
	
	public OpcionesUsuarioResponse leerOpcionesPorUsuario(OpcionesUsuarioRequest opcionesUsuarioRequest,final int timeOut) throws SOAPException{
		OpcionesUsuarioResponse opcionesUsuarioResponse = new OpcionesUsuarioResponse();
		StringBuffer msgInfo = new StringBuffer();
		long startTime = 0L;
        long endTime = 0L;
        
        StringBuffer sbRequest = new StringBuffer();
		SOAPConnection conn = null;

		sbRequest.append(soapEnvelopeStartTag);
		sbRequest.append("<ws:leerOpcionesPorUsuario>");
		sbRequest.append("<opc:OpcionesUsuarioRequest>");
		sbRequest.append("<opc:usuario>"+opcionesUsuarioRequest.getUsuario()+"</opc:usuario>");
		sbRequest.append("<opc:aplicacion>"+opcionesUsuarioRequest.getAplicacion()+"</opc:aplicacion>");
		sbRequest.append("</opc:OpcionesUsuarioRequest>");
		sbRequest.append("</ws:leerOpcionesPorUsuario>");
		sbRequest.append(soapEnvelopeEndTag);
		
		logger.info(sbRequest.toString());
		try{
			MessageFactory mf = MessageFactory.newInstance();
			MimeHeaders headers = new MimeHeaders();
			SOAPMessage smsg = mf.createMessage(headers, new ByteArrayInputStream(sbRequest.toString().getBytes()));
			conn = SOAPConnectionFactory.newInstance().createConnection();
			startTime = System.currentTimeMillis();
			
			URL endpoint = new URL(null, 
					url, 
	                new URLStreamHandler() {
	                   protected URLConnection openConnection(URL url) throws IOException{  
	                	   URL clone_url = new URL(url.toString());
	                	   HttpURLConnection clone_urlconnection =(HttpURLConnection) clone_url.openConnection(); 
	                       clone_urlconnection.setConnectTimeout(timeOut);
		                   clone_urlconnection.setReadTimeout(timeOut);
	                	   return(clone_urlconnection);
	                   }
	            }); 
			
			SOAPMessage smResponse = conn.call(smsg, endpoint);
			smResponse.writeTo(System.out);
			endTime = System.currentTimeMillis();
			
			endTime = System.currentTimeMillis();
			if(smResponse != null){
				List<ListAbreviatura> lista=new ArrayList<ListAbreviatura>();
				SOAPBody soapBody = smResponse.getSOAPBody();
				Iterator soapBodyIterator = soapBody.getChildElements();
				soapBody = null;
				if(soapBodyIterator.hasNext()){
					SOAPElement soapBodyElement = (SOAPElement) soapBodyIterator.next();
					Iterator getSubIterator = soapBodyElement.getChildElements();
					if(getSubIterator.hasNext()){
						SOAPElement getSubElement = (SOAPElement) getSubIterator.next();
						Iterator payerIterator = getSubElement.getChildElements();
						while(payerIterator.hasNext()){
							SOAPElement payerElement = (SOAPElement) payerIterator.next();
							Iterator subSubElemet = payerElement.getChildElements();
							//System.out.println("payerElement "+payerElement.getTagName()+", "+payerElement.getValue());
							while(subSubElemet.hasNext()){
								SOAPElement iterates = (SOAPElement) subSubElemet.next();
								System.out.println("iterates "+iterates.getTagName()+", "+iterates.getValue());
								if(iterates.getTagName().contains("estado")){
									opcionesUsuarioResponse.setEstado(iterates.getValue());
								}else if(iterates.getTagName().contains("mensaje")){
									opcionesUsuarioResponse.setMensaje(iterates.getValue());
								}else if(iterates.getTagName().contains("menuItem")){
									Iterator cap = iterates.getChildElements();
									while(cap.hasNext()){
										SOAPElement caps = (SOAPElement) cap.next();
										Iterator iterates2 = caps.getChildElements();
										if(caps.getTagName().contains("datosMenu")){
											ListAbreviatura tmp=new ListAbreviatura();
											while(iterates2.hasNext()){
												SOAPElement caps2 = (SOAPElement) iterates2.next();
												System.out.println("caps2 "+caps2.getTagName()+", "+caps2.getValue());
												if(caps2.getTagName().contains("abreviatura")){
													tmp.setAbreviatura(caps2.getValue());
												}else if(caps2.getTagName().contains("descripcion")){
													tmp.setDescripcion(caps2.getValue());
												}
											}
											
											lista.add(tmp);
										}
									}
									opcionesUsuarioResponse.setAbreviatura(lista);
								}
								
							}
						}
					}
				}
				
				msgInfo.append("leerOpcionesPorUsuario" + "\t");
		        msgInfo.append("Usuario : " + opcionesUsuarioRequest.getUsuario()+ "\t");
		        msgInfo.append("Aplicacion : " + opcionesUsuarioRequest.getAplicacion() + "\t");
		        msgInfo.append("Return status [Estado : " + opcionesUsuarioResponse.getEstado()+ ",\t");
		        msgInfo.append("Mensaje : " + opcionesUsuarioResponse.getMensaje() + "]\n");
		        if(opcionesUsuarioResponse.getAbreviatura()!=null){
		        	if(opcionesUsuarioResponse.getAbreviatura().size()>0){
			        	for(int i=0;i<opcionesUsuarioResponse.getAbreviatura().size();i++){
			        		msgInfo.append("DatosMenu "+i+": [Abreviatura : " +opcionesUsuarioResponse.getAbreviatura().get(i).getAbreviatura() +", Descripcion "+opcionesUsuarioResponse.getAbreviatura().get(i).getDescripcion()+"], \t");
					    }
			        }
		        }
		        msgInfo.append((endTime - startTime) + "ms\t");
		        logger.info(msgInfo.toString());
		        msgInfo=null;
			}else {
				  msgInfo.append("leerOpcionesPorUsuario" + "\t");
				  msgInfo.append("Usuario : " + opcionesUsuarioRequest.getUsuario()+ "\t");
			      msgInfo.append("Aplicacion : " + opcionesUsuarioRequest.getAplicacion() + "\t");
			      msgInfo.append("NO OK Response is null" + "\t");
				  msgInfo.append((endTime - startTime) + "ms\t");
				  logger.info(msgInfo.toString());
				  opcionesUsuarioResponse.setEstado("-1");
				  opcionesUsuarioResponse.setMensaje("NO OK Response is null");
				  msgInfo=null;
			   }
			
		}catch(IOException ioex){
			endTime = System.currentTimeMillis();
			msgInfo.append("ws-leerOpcionesPorUsuario" + "\t");
	        msgInfo.append("[" + opcionesUsuarioRequest.getUsuario() + ","+ opcionesUsuarioRequest.getAplicacion()+"]" + "\t");
	        msgInfo.append("TriacionesGenerico WS\t");
	        msgInfo.append("No OK\t");
	        msgInfo.append("IOException=" + ioex.getMessage() + "\t");
	        msgInfo.append((endTime - startTime) + "ms\n"); 
	        logger.info(msgInfo.toString());
	        opcionesUsuarioResponse.setEstado("-1");
	        opcionesUsuarioResponse.setMensaje("IOException=" + ioex.getMessage());
	        msgInfo=null;
		}catch (SOAPException soapex) {
			endTime = System.currentTimeMillis();
			if(soapex.toString().contains("Message send failed")){
				msgInfo.append("ws-leerOpcionesPorUsuario" + "\t");
				 msgInfo.append("[" + opcionesUsuarioRequest.getUsuario() + ","+ opcionesUsuarioRequest.getAplicacion()+"]" + "\t");
		        msgInfo.append("ws-leerDatosUsuario WS\t");
		        msgInfo.append("No OK\t");
		        msgInfo.append("TimeOut SOAPException=" + soapex.getMessage() + "\t");
		        msgInfo.append((endTime - startTime) + "ms\n"); 
		        logger.info(msgInfo.toString());
		        opcionesUsuarioResponse.setEstado("-1");
		        opcionesUsuarioResponse.setMensaje("TimeOut SOAPException=" + soapex.getMessage());
		        msgInfo=null;
	        }else{
				msgInfo.append("ws-leerOpcionesPorUsuario" + "\t");
				 msgInfo.append("[" + opcionesUsuarioRequest.getUsuario() + ","+ opcionesUsuarioRequest.getAplicacion()+"]" + "\t");
		        msgInfo.append("ws-leerDatosUsuario WS\t");
		        msgInfo.append("No OK\t");
		        msgInfo.append("SOAPException=" + soapex.getMessage() + "\t");
		        msgInfo.append((endTime - startTime) + "ms\n"); 
		        opcionesUsuarioResponse.setEstado("-1");
		        opcionesUsuarioResponse.setMensaje("SOAPException=" + soapex.getMessage());
		        logger.info(msgInfo.toString());
		        msgInfo=null;
	        }
	        logger.info(msgInfo.toString());
	        msgInfo=null;
		}catch (Exception ex) {
			endTime = System.currentTimeMillis();
			msgInfo.append("ws-leerOpcionesPorUsuario" + "\t");
			msgInfo.append("[" + opcionesUsuarioRequest.getUsuario() + ","+ opcionesUsuarioRequest.getAplicacion()+"]" + "\t");
	        msgInfo.append("ws-leerDatosUsuario WS\t");
	        msgInfo.append("No OK\t");
	        msgInfo.append("Exception=" + ex.getMessage() + "\t");
	        msgInfo.append((endTime - startTime) + "ms\n"); 
	        logger.info(msgInfo.toString()); 
	        opcionesUsuarioResponse.setEstado("-1");
	        opcionesUsuarioResponse.setMensaje("Exception=" + ex.getMessage());
	        msgInfo=null;
		}finally{
			conn.close(); // close connection
			conn = null;
		}
		return opcionesUsuarioResponse;		
	}
	
	public void init() throws Exception{
		try{
			logger.info("Initializing LeerOpcionesPorUsuarioManager Web Service Manager...");
			logger.info("LeerOpcionesPorUsuarioManager Web Service Address = " + address);
			logger.info("LeerOpcionesPorUsuarioManager Web Service Port = " + port);
			logger.info("LeerOpcionesPorUsuarioManager Web Service = " + service);
			url = "http://"+ address+":"+port+"/"+service;
			logger.info("LeerOpcionesPorUsuarioManager URL = "+url);
			logger.info("LeerOpcionesPorUsuarioManager Web Service Manager initialized successfully");
		} catch (Exception _ex) {
			_ex.printStackTrace();
			throw new Exception("Unable to initialize LeerOpcionesPorUsuarioManager webservice manager");
		}
	}
	
}
